<script setup lang="ts">
import { QueryEquipmentStatusClassNumCountRes, queryEquipmentStatusClassNumCount, queryTaskStatus } from "@/api/leadScreenNew";
import { isHasPermission } from "@/utils/auth";
import { debounce } from "@pureadmin/utils";
import dayjs from "dayjs";
import * as echarts from "echarts";
import { onMounted, onUnmounted, ref } from "vue";
import { usePolling } from "./hooks";

const charts = ref([]);
const barChartRef = ref();
const BAR_CONFIG = {
  yunxing: {
    reat: "rgba(8, 134, 92, 1)",
    bar: {
      type: "linear",
      x: 0,
      y: 0,
      x2: 0,
      y2: 1,
      global: false,
      colorStops: [
        {
          offset: 0,
          color: "rgba(8, 134, 92, 0.56)" // 最左边
        },
        {
          offset: 1,
          color: "rgba(8, 134, 92, 1)"
        }
      ]
    }
  },
  daiji: {
    reat: "rgba(34, 132, 194, 1)",
    bar: {
      type: "linear",
      x: 0,
      y: 0,
      x2: 0,
      y2: 1,
      global: false,
      colorStops: [
        {
          offset: 0,
          color: "rgba(34, 132, 194, 0.56)" // 最左边
        },
        {
          offset: 1,
          color: "rgba(34, 132, 194, 1)"
        }
      ]
    }
  },
  daibing: {
    reat: "rgba(157, 119, 7, 1)",
    bar: {
      type: "linear",
      x: 0,
      y: 0,
      x2: 0,
      y2: 1,
      global: false,
      colorStops: [
        {
          offset: 0,
          color: "rgba(157, 119, 7, 0.56)" // 最左边
        },
        {
          offset: 1,
          color: "rgba(157, 119, 7, 1)"
        }
      ]
    }
  },
  lixian: {
    reat: "rgba(200, 77, 159, 1)",
    bar: {
      type: "linear",
      x: 0,
      y: 0,
      x2: 0,
      y2: 1,
      global: false,
      colorStops: [
        {
          offset: 0,
          color: "rgba(200, 77, 159, 0.56)" // 最左边
        },
        {
          offset: 1,
          color: "rgba(200, 77, 159, 1)"
        }
      ]
    }
  },
  guzhang: {
    reat: "rgba(200, 77, 84, 1)",
    bar: {
      type: "linear",
      x: 0,
      y: 0,
      x2: 0,
      y2: 1,
      global: false,
      colorStops: [
        {
          offset: 0,
          color: "rgba(200, 77, 84, 0.56)" // 最左边
        },
        {
          offset: 1,
          color: "rgba(200, 77, 84, 1)"
        }
      ]
    }
  }
};
// 机械科总数329正常325，电科总数3528正常3344，水科总数581正常581，气化科总数2515正常2491
const EQUIP_STATIC_DATA = {
  machineStatusNum: [
    {
      eqpRunStatus: "1",
      eqpRunStatusDesc: "运行",
      statusNum: 1591
    },
    {
      eqpRunStatus: "3",
      eqpRunStatusDesc: "带病",
      statusNum: 0
    },
    {
      eqpRunStatus: "2",
      eqpRunStatusDesc: "故障",
      statusNum: 0
    },
    {
      eqpRunStatus: "5",
      eqpRunStatusDesc: "待机",
      statusNum: 0
    },
    {
      eqpRunStatus: "4",
      eqpRunStatusDesc: "离线",
      statusNum: 0
    }
  ],
  waterStatusNum: [
    {
      eqpRunStatus: "1",
      eqpRunStatusDesc: "运行",
      statusNum: 1513
    },
    {
      eqpRunStatus: "3",
      eqpRunStatusDesc: "带病",
      statusNum: 0
    },
    {
      eqpRunStatus: "2",
      eqpRunStatusDesc: "故障",
      statusNum: 0
    },
    {
      eqpRunStatus: "5",
      eqpRunStatusDesc: "待机",
      statusNum: 0
    },
    {
      eqpRunStatus: "4",
      eqpRunStatusDesc: "离线",
      statusNum: 0
    }
  ],
  gasStatusNum: [
    {
      eqpRunStatus: "1",
      eqpRunStatusDesc: "运行",
      statusNum: 1068
    },
    {
      eqpRunStatus: "3",
      eqpRunStatusDesc: "带病",
      statusNum: 0
    },
    {
      eqpRunStatus: "2",
      eqpRunStatusDesc: "故障",
      statusNum: 0
    },
    {
      eqpRunStatus: "5",
      eqpRunStatusDesc: "待机",
      statusNum: 0
    },
    {
      eqpRunStatus: "4",
      eqpRunStatusDesc: "离线",
      statusNum: 0
    }
  ],
  electrictityStatusNum: [
    {
      eqpRunStatus: "1",
      eqpRunStatusDesc: "运行",
      statusNum: 846
    },
    {
      eqpRunStatus: "3",
      eqpRunStatusDesc: "带病",
      statusNum: 0
    },
    {
      eqpRunStatus: "2",
      eqpRunStatusDesc: "故障",
      statusNum: 0
    },
    {
      eqpRunStatus: "5",
      eqpRunStatusDesc: "待机",
      statusNum: 0
    },
    {
      eqpRunStatus: "4",
      eqpRunStatusDesc: "离线",
      statusNum: 0
    }
  ]
};
let barChart = null;
const initBarChart = async () => {
  if (!barChartRef.value) {
    return;
  }
  let data: any = {};
  if (!isHasPermission("EQUIP_REAL_DATA")) {
    data = EQUIP_STATIC_DATA;
  } else {
    data = await queryEquipmentStatusClassNumCount();
  }
  const seriesData = [...Array(5)].map(() => []);
  Object.values(data as QueryEquipmentStatusClassNumCountRes).forEach(child => {
    child.forEach(element => {
      const index = element.eqpRunStatus - 1;
      seriesData[index].push(element.statusNum);
    });
  });
  const chartDom = barChartRef.value;
  if (!barChart) {
    barChart = echarts.init(chartDom);
  }
  let xData = ["机械科", "电科", "水科", "气化科"];

  let barWidth = 16;
  const option = {
    // 图例
    legend: {
      itemGap: 16,
      top: 0,
      right: 0,
      itemWidth: 8,
      itemHeight: 8,
      icon: "rect",
      data: [
        {
          name: "运行",
          itemStyle: {
            color: "#08865C"
          }
        },
        {
          name: "待机",
          itemStyle: {
            color: "#2284C2"
          }
        },
        {
          name: "带病",
          itemStyle: {
            color: "#9D7707"
          }
        },
        {
          name: "离线",
          itemStyle: {
            color: "#C84D9F"
          }
        },
        {
          name: "故障",
          itemStyle: {
            color: "#C84D54"
          }
        }
      ],
      textStyle: {
        color: "rgba(255,255,255,0.62)",
        fontSize: 12
      }
    },
    color: "rgba(255,255,255,0.62)",
    /**区域位置*/
    grid: {
      left: 0,
      right: 0,
      top: "20%",
      bottom: "5%",
      containLabel: true
    },
    //X轴
    xAxis: {
      data: xData,
      type: "category",
      axisLine: {
        lineStyle: {
          color: "rgba(255,255,255,0.2)",
          shadowOffsetX: "20"
        }
      },
      splitLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: "rgba(255,255,255,0.62)",
        margin: 15,
        fontSize: 12
      }
    },
    yAxis: {
      name: "个",
      nameTextStyle: {
        color: "rgba(255,255,255,0.62)",
        fontSize: 11
      },
      show: true,
      splitNumber: 4,
      axisLine: {
        show: false
      },
      splitLine: {
        show: true,
        lineStyle: {
          type: "dashed",
          color: "rgba(255,255,255,0.2)"
        }
      },
      axisLabel: {
        color: "rgba(255,255,255,0.62)",
        margin: 15,
        fontSize: 11
      }
    },
    series: [
      {
        name: "运行",
        type: "bar",
        barWidth: barWidth,
        barGap: "100%",
        itemStyle: {
          normal: {
            color: function () {
              return BAR_CONFIG.yunxing.bar;
            }
          }
        },
        data: seriesData[0],
        label: {
          show: true,
          position: "top",
          color: " rgba(255,255,255,0.9)"
        }
      },
      {
        z: 2,
        type: "pictorialBar",
        data: seriesData[0],
        symbol: "diamond",
        symbolOffset: ["-403%", "50%"],
        symbolSize: [barWidth, barWidth * 0.5],
        itemStyle: {
          normal: {
            color: BAR_CONFIG.yunxing.reat
          }
        }
      },
      {
        z: 3,
        type: "pictorialBar",
        symbolPosition: "end",
        data: seriesData[0],
        symbol: "diamond",
        symbolOffset: ["-403%", "-50%"],
        symbolSize: [barWidth, barWidth * 0.5],
        itemStyle: {
          normal: {
            borderWidth: 0,
            color: BAR_CONFIG.yunxing.reat
          }
        }
      },
      // ---------------------分割线---------------------
      {
        name: "待机",
        type: "bar",
        barWidth: barWidth,
        itemStyle: {
          normal: {
            color: function () {
              return BAR_CONFIG.daiji.bar;
            }
          }
        },
        data: seriesData[4],
        label: {
          show: true,
          position: "top",
          color: " rgba(255,255,255,0.9)"
        }
      },
      {
        z: 2,
        type: "pictorialBar",
        data: seriesData[4],
        symbol: "diamond",
        symbolOffset: ["-200%", "50%"],
        symbolSize: [barWidth, barWidth * 0.5],
        itemStyle: {
          normal: {
            color: BAR_CONFIG.daiji.reat
          }
        }
      },
      {
        z: 3,
        type: "pictorialBar",
        symbolPosition: "end",
        data: seriesData[4],
        symbol: "diamond",
        symbolOffset: ["-200%", "-50%"],
        symbolSize: [barWidth, barWidth * 0.5],
        itemStyle: {
          normal: {
            borderWidth: 0,
            color: BAR_CONFIG.daiji.reat
          }
        }
      },
      // ---------------------分割线---------------------
      {
        name: "带病",
        type: "bar",
        barWidth: barWidth,
        itemStyle: {
          normal: {
            color: function () {
              return BAR_CONFIG.daibing.bar;
            }
          }
        },
        data: seriesData[2],
        label: {
          show: true,
          position: "top",
          color: " rgba(255,255,255,0.9)"
        }
      },
      {
        z: 2,
        type: "pictorialBar",
        data: seriesData[2],
        symbol: "diamond",
        symbolOffset: ["3%", "50%"],
        symbolSize: [barWidth, barWidth * 0.5],
        itemStyle: {
          normal: {
            color: BAR_CONFIG.daibing.reat
          }
        }
      },
      {
        z: 3,
        type: "pictorialBar",
        symbolPosition: "end",
        data: seriesData[2],
        symbol: "diamond",
        symbolOffset: ["3%", "-50%"],
        symbolSize: [barWidth, barWidth * 0.5],
        itemStyle: {
          normal: {
            borderWidth: 0,
            color: BAR_CONFIG.daibing.reat
          }
        }
      },
      // ---------------------分割线---------------------
      {
        name: "离线",
        type: "bar",
        barWidth: barWidth,
        itemStyle: {
          normal: {
            color: function () {
              return BAR_CONFIG.lixian.bar;
            }
          }
        },
        data: seriesData[3],
        label: {
          show: true,
          position: "top",
          color: " rgba(255,255,255,0.9)"
        }
      },
      {
        z: 2,
        type: "pictorialBar",
        data: seriesData[3],
        symbol: "diamond",
        symbolOffset: ["200%", "50%"],
        symbolSize: [barWidth, barWidth * 0.5],
        itemStyle: {
          normal: {
            color: BAR_CONFIG.lixian.reat
          }
        }
      },
      {
        z: 3,
        type: "pictorialBar",
        symbolPosition: "end",
        data: seriesData[3],
        symbol: "diamond",
        symbolOffset: ["200%", "-50%"],
        symbolSize: [barWidth, barWidth * 0.5],
        itemStyle: {
          normal: {
            borderWidth: 0,
            color: BAR_CONFIG.lixian.reat
          }
        }
      },
      // ---------------------分割线---------------------
      {
        name: "故障",
        type: "bar",
        barWidth: barWidth,
        itemStyle: {
          normal: {
            color: function () {
              return BAR_CONFIG.guzhang.bar;
            }
          }
        },
        data: seriesData[1],
        label: {
          show: true,
          position: "top",
          color: " rgba(255,255,255,0.9)"
        }
      },
      {
        z: 2,
        type: "pictorialBar",
        data: seriesData[1],
        symbol: "diamond",
        symbolOffset: ["403%", "50%"],
        symbolSize: [barWidth, barWidth * 0.5],
        itemStyle: {
          normal: {
            color: BAR_CONFIG.guzhang.reat
          }
        }
      },
      {
        z: 3,
        type: "pictorialBar",
        symbolPosition: "end",
        data: seriesData[1],
        symbol: "diamond",
        symbolOffset: ["403%", "-50%"],
        symbolSize: [barWidth, barWidth * 0.5],
        itemStyle: {
          normal: {
            borderWidth: 0,
            color: BAR_CONFIG.guzhang.reat
          }
        }
      }
    ]
  };

  option && barChart.setOption(option);
  if (!charts.value.includes(barChart)) {
    charts.value.push(barChart);
  }
};
const PROGRESS_CONFIG = [
  {
    key: "EQUIPMENT_CHECK",
    name: "巡检任务",
    icon: "xunjian"
  },
  {
    key: "MAINTENANCE_WORK_ORDER",
    name: "维修任务",
    icon: "weixiu"
  },
  {
    key: "PMS",
    name: "保养任务",
    icon: "baoyang"
  },
  {
    key: "MISSING",
    name: "安全管理",
    icon: "anquan"
  }
];
const pieChartRef = ref();
const taskData = ref({});
const total = ref(0);
let pieChart = null;
const initPieChart = async () => {
  if (!pieChartRef.value) {
    return;
  }
  // 1、数据请求
  const data =
    (await queryTaskStatus({
      startTime: dayjs().format("YYYY-MM-DD 00:00:00"),
      endTime: dayjs().format("YYYY-MM-DD 23:59:59"),
      taskModuleTypeCode: PROGRESS_CONFIG.map(item => item.key)
    })) || [];
  const obj = {};
  total.value = 0;
  data.forEach(item => {
    obj[item.taskModuleName] = item;
    total.value += item.totalTasks;
  });
  taskData.value = obj;
  resetProgressWidth();
  const seriesData = PROGRESS_CONFIG.map(item => ({
    name: item.name,
    value: obj[item.key]?.totalTasks || 0
  }));
  // 2、图表渲染
  // charts.value.forEach(chart => {
  //   chart.dispose();
  // });
  const chartDom = pieChartRef.value;
  if (!pieChart) {
    pieChart = echarts.init(chartDom, null, { renderer: "svg" });
  }

  let option;

  option = {
    tooltip: {
      trigger: "item",
      appendToBody: true,
      formatter: function (params) {
        const { name, data, color } = params;
        return `<div style="display:flex;align-items:center;">
            <div style="width: 10px;height: 10px;border-radius:50%;background: ${color};margin-right:3px;"></div>
            <div style="color: rgba(255,255,255,0.9);line-height: 18px;margin-right:12px">${name}</div>
            <div  style="color: rgba(255,255,255,0.9);line-height: 18px;font-weight: 600;">${((data.value / total.value) * 100).toFixed(1)}%</div>
          </div>`;
      },
      borderColor: "transparent",
      backgroundColor: "rgba(9,28,59,0.8)",
      padding: [3, 8],
      textStyle: {
        fontSize: 12
      },
      extraCssText:
        "box-shadow: 0px 5px 5px -3px rgba(0,0,0,0.1), 0px 8px 10px 1px rgba(0,0,0,0.06), 0px 3px 14px 2px rgba(0,0,0,0.05);border-radius: 3px;backdrop-filter: blur(1px);"
    },
    devicePixelRatio: window.devicePixelRatio || 2,
    grid: {
      left: 0,
      right: 0,
      top: 0,
      bottom: 0
    },
    legend: {
      show: false
    },
    color: ["#1F8BCF", "#976CBC", "#CB6D8A", "#BB785B"],
    series: [
      {
        name: "今日任务",
        type: "pie",
        radius: ["60%", "82%"],
        avoidLabelOverlap: false,
        padAngle: 0,
        itemStyle: {
          borderRadius: 0,
          color: "#fff"
        },
        label: {
          show: false,
          position: "center"
        },
        emphasis: {
          disabled: true
        },
        labelLine: {
          show: false
        },
        tooltip: { show: false },
        data: [{ value: 1 }]
      }, // 白色背景

      {
        name: "今日任务",
        type: "pie",
        radius: ["60%", "82%"],
        avoidLabelOverlap: false,
        padAngle: 1,
        itemStyle: {
          borderRadius: 0
        },
        label: {
          show: false,
          position: "center"
        },
        emphasis: {
          label: {
            show: false,
            fontSize: 14,
            fontWeight: "bold"
          }
        },
        labelLine: {
          show: false
        },
        data: seriesData
      }
    ]
  };

  option && pieChart.setOption(option);
  if (!charts.value.includes(pieChart)) {
    charts.value.push(pieChart);
  }
};
const init = () => {
  initBarChart();
  initPieChart();
};
// 轮询
usePolling(initBarChart, {
  pollingInterval: 30 * 1000
});
usePolling(initPieChart, {
  pollingInterval: 10 * 60 * 1000
});
const progressRef = ref();
const progressWidth = ref([]);
const getItemContentWidth = (data, index) => {
  if (!data?.totalTasks || !data?.doneTasks || !progressRef.value[index]) {
    return 0;
  }
  const per = data.doneTasks / data.totalTasks;
  const ele = progressRef.value[index].parentNode;
  const width = ele.offsetWidth * per + "px";
  return width;
};
const resetProgressWidth = () => {
  progressWidth.value = [];
  PROGRESS_CONFIG.forEach((item, index) => {
    const width = getItemContentWidth(taskData.value[item.key], index);
    progressWidth.value.push(width);
  });
};
// 处理窗口大小变化
const handleResize = debounce(() => {
  // 1、图表
  charts.value.forEach(chart => {
    chart.resize();
  });
  // 2、进度条
  resetProgressWidth();
}, 60);
onMounted(() => {
  init();
  window.addEventListener("resize", handleResize);
});
onUnmounted(() => {
  window.removeEventListener("resize", handleResize);
  charts.value.forEach(chart => {
    chart.dispose();
  });
});
</script>
<template>
  <section>
    <px-row :gutter="8">
      <!-- 设备运行状态 -->
      <px-col :span="12" class="screen-card-box">
        <div class="card-content">
          <div class="card-title">设备运行状态</div>
          <div class="bar-chart" ref="barChartRef"></div>
        </div>
      </px-col>
      <!-- 今日任务 -->
      <px-col :span="12" class="screen-card-box">
        <div class="card-content">
          <div class="card-title">今日任务</div>
          <div class="flex-row">
            <!-- 环形图 -->
            <div class="pie-chart-box">
              <div class="circle">
                <div class="circle-title">任务总数</div>
                <div class="circle-num">{{ total }}</div>
              </div>
              <div class="pie-chart" ref="pieChartRef"></div>
            </div>
            <!-- 任务进度条 -->
            <px-row class="progress" :gutter="40">
              <px-col :span="12" v-for="(task, index) in PROGRESS_CONFIG" :key="task.icon" class="progress-content">
                <dl class="flex-row w-100">
                  <dt class="progress-icon" :style="`background-image: url(/ifp-web-static/image/all/leadScreenNew/${task.icon}.png);`"></dt>
                  <dd class="w-100">
                    <div class="progress-name flex-row">
                      <span>{{ task.name }}</span
                      ><span class="tasksNum"
                        ><span class="doneTasks">{{
                          taskData[task.key]?.doneTasks || taskData[task.key]?.doneTasks === 0 ? taskData[task.key]?.doneTasks : "--"
                        }}</span
                        >/<span>{{
                          taskData[task.key]?.totalTasks || taskData[task.key]?.totalTasks === 0 ? taskData[task.key]?.totalTasks : "--"
                        }}</span></span
                      >
                    </div>
                    <div class="progress-item-box">
                      <div class="progress-item">
                        <div ref="progressRef" :class="['progress-item-content', task.icon].join(' ')" :style="`width:${progressWidth[index]}`">
                          <span class="item-content-num" v-if="taskData[task.key]?.totalTasks"
                            >{{ ((taskData[task.key]?.doneTasks / taskData[task.key]?.totalTasks) * 100).toFixed(0) }}%</span
                          >
                        </div>
                      </div>
                    </div>
                  </dd>
                </dl>
              </px-col>
            </px-row>
          </div>
        </div>
      </px-col>
    </px-row>
  </section>
</template>
<style lang="scss" scoped>
@import url("../card.scss");
.screen-card-box {
  height: 182rpx;
}
.bar-chart {
  width: 100%;
  height: 139rpx;
  padding: 0 12rpx;
}
.pie-chart-box {
  width: 145rpx;
  height: 145rpx;
  margin-left: 10rpx;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-shrink: 0;
  .circle {
    width: 80rpx;
    height: 80rpx;
    box-shadow: inset 0px 0px 18rpx 0px #005eff;
    border: 1px solid #059aff;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    position: relative;
    z-index: 10;
    &-title {
      font-size: 14rpx;
      font-family: AlibabaPuHuiTi-Regular, AlibabaPuHuiTi;
      font-weight: 400;
      color: rgba(255, 255, 255, 0.9);
      line-height: 20rpx;
    }
    &-num {
      font-size: 24rpx;
      font-family: AlibabaPuHuiTiM;
      color: rgba(255, 255, 255, 0.9);
      line-height: 33rpx;
    }
  }
}
.pie-chart {
  width: 145rpx;
  height: 145rpx;
  position: absolute;
  top: 0;
  right: 0;
}
.flex-row {
  padding: 0 9rpx;
  display: flex;
  align-items: center;
}
.progress {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  flex-grow: 1;
  .progress-content:nth-child(n + 3) {
    margin-top: 28rpx;
  }
  .progress-icon {
    width: 44rpx;
    height: 38rpx;
    margin-right: 8rpx;
    flex-shrink: 0;
    background-repeat: no-repeat;
    background-position: center center;
    background-size: contain;
  }
  .progress-name {
    font-size: 16rpx;
    font-family: AlibabaPuHuiTiM;
    color: rgba(255, 255, 255, 0.9);
    line-height: 22rpx;
    margin-bottom: 8rpx;
    justify-content: space-between;
  }
  .doneTasks {
    height: 22rpx;
    font-size: 20rpx;
    font-family: AlibabaPuHuiTiM;
    color: #3cb1fb;
    line-height: 22rpx;
  }
  .tasksNum {
    font-size: 16rpx;
    font-family: AlibabaPuHuiTi-Regular, AlibabaPuHuiTi;
    font-weight: 400;
    color: rgba(255, 255, 255, 0.9);
    line-height: 22rpx;
  }
  .progress-item-box {
    width: 100%;
    border-radius: 9rpx;
    overflow: hidden;
  }
  .progress-item {
    width: 100%;
    background: linear-gradient(180deg, rgba(9, 18, 40, 0.36) 0%, rgba(13, 58, 136, 0.36) 100%);
    border-radius: 9rpx;
    border: 2px solid rgba(36, 140, 219, 0.24);
  }
  .progress-item-content {
    width: 0;
    height: 12rpx;
    border-radius: 9rpx;
    font-size: 12rpx;
    font-family: AlibabaPuHuiTiM;
    color: rgba(255, 255, 255, 0.9);
    line-height: 12rpx;
    transition: all 0.3s linear;
    text-align: right;
    .item-content-num {
      margin-right: 6rpx;
    }
    &.xunjian {
      background: #1f8bcf;
      box-shadow: 0px 4px 12px 0px rgba(60, 177, 251, 0.4);
    }
    &.weixiu {
      background: #976cbc;
      box-shadow: 0px 4px 12px 0px rgba(7, 168, 114, 0.4);
    }
    &.baoyang {
      background: #cb6d8a;
      box-shadow: 0px 4px 12px 0px rgba(210, 158, 8, 0.4);
    }
    &.anquan {
      background: #bb785b;
      box-shadow: 0px 4px 12px 0px rgba(255, 112, 207, 0.4);
    }
  }
  .w-100 {
    width: 100%;
  }
}
</style>
